home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / COMMS / C101.ZIP / UUPC11XS.ZIP / UUCICO / CHECKTIM.C next >
C/C++ Source or Header  |  1992-11-12  |  13KB  |  316 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    c h e c k t i m . c                                             */
  3. /*                                                                    */
  4. /*    Time of day validation routine for UUPC/extended                */
  5. /*                                                                    */
  6. /*    Copyright (c) 1989, 1990, 1991 by Andrew H. Derbyshire          */
  7. /*                                                                    */
  8. /*    Change history:                                                 */
  9. /*       20 Apr 1991 Broken out of dcpsys.c                    ahd    */
  10. /*--------------------------------------------------------------------*/
  11.  
  12. /*--------------------------------------------------------------------*/
  13. /*                        System include files                        */
  14. /*--------------------------------------------------------------------*/
  15.  
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <stdlib.h>
  19. #include <time.h>
  20.  
  21. /*--------------------------------------------------------------------*/
  22. /*                    UUPC/extended include files                     */
  23. /*--------------------------------------------------------------------*/
  24.  
  25. #include "lib.h"
  26. #include "checktim.h"
  27.  
  28. /*--------------------------------------------------------------------*/
  29. /*                          Global variables                          */
  30. /*--------------------------------------------------------------------*/
  31.  
  32. currentfile();
  33.  
  34. /*--------------------------------------------------------------------*/
  35. /*                          Local functions                           */
  36. /*--------------------------------------------------------------------*/
  37.  
  38. static char checkone( char *input, size_t hhmm, int weekday );
  39.  
  40. /*--------------------------------------------------------------------*/
  41. /*   The following day values are based on the fact the               */
  42. /*   localtime() call returns the day of the week as a value zero     */
  43. /*   (0) through six (6), which is converted into the bit number      */
  44. /*   and then AND'ed against the date mask.                           */
  45. /*--------------------------------------------------------------------*/
  46.  
  47. #define SUN 0x80
  48. #define MON 0x40
  49. #define TUE 0x20
  50. #define WED 0x10
  51. #define THU 0x08
  52. #define FRI 0x04
  53. #define SAT 0x02
  54. #define NEVER 0x00
  55. #define WEEKEND (SAT | SUN)
  56. #define WEEKDAY (MON | TUE | WED | THU | FRI)
  57. #define ANY (WEEKEND | WEEKDAY)
  58.  
  59. /*--------------------------------------------------------------------*/
  60. /*   Table of values for schedules.  Based on values given for        */
  61. /*   legal schedule keywords in "Managing uucp and Usenet" by         */
  62. /*   O'Reilly & Associates.  Multiple entries for a single keyword    */
  63. /*   are processed in logical OR fashion, just as multiple entries    */
  64. /*   for the same host in L.sys are treated in a logical OR           */
  65. /*   fashion.                                                         */
  66. /*                                                                    */
  67. /*   Timing windows are adjusted five minutes away from higher        */
  68. /*   telephone rates in an attempt to avoid massive charges           */
  69. /*   because of inaccurate PC clocks and the fact that a telephone    */
  70. /*   call generally requires more than one minute if the system is    */
  71. /*   trying to do useful work.                                        */
  72. /*                                                                    */
  73. /*   Does not support multiple keywords in one token                  */
  74. /*   (TuFr0800-0805), but allows multiple tokens                      */
  75. /*   (Tu0800-805,Fr0800-0805) on one line.                            */
  76. /*                                                                    */
  77. /*   The NonPeak keyword has been corrected to the current (May       */
  78. /*   1989) NonPeak hours for Telenet's PC-Pursuit.  However, keep     */
  79. /*   in mind the PC-Pursuit customer agreement specifies that you     */
  80. /*   can't use PC-Pursuit to network multiple PC's, so thou shalt     */
  81. /*   not use PC-Pursuit from a central mail server.  *sigh*           */
  82. /*                                                                    */
  83. /*   I also have Reach-Out America from ATT, for which night rates    */
  84. /*   begin at 10:00 pm.  It is duly added to the table.               */
  85. /*--------------------------------------------------------------------*/
  86.  
  87. static struct Table {
  88.    char *keyword;
  89.    int wdays;
  90.    unsigned int start;
  91.    unsigned int end;
  92.  
  93. } table[] = {
  94.    { "Any",     ANY,         0, 2400},
  95.    { "Wk",      WEEKDAY,     0, 2400},
  96.    { "Su",      SUN,         0, 2400},
  97.    { "Mo",      MON,         0, 2400},
  98.    { "Tu",      TUE,         0, 2400},
  99.    { "We",      WED,         0, 2400},
  100.    { "Th",      THU,         0, 2400},
  101.    { "Fr",      FRI,         0, 2400},
  102.    { "Sa",      SAT,         0, 2400},
  103.    { "Evening", WEEKDAY,  1705,  755},
  104.    { "Evening", WEEKEND,     0, 2400},
  105.    { "Night",   WEEKDAY,  2305,  755},
  106.    { "Night",   SAT,         0, 2400},
  107.    { "Night",   SUN,      2305, 1655},
  108.    { "NonPeak", WEEKDAY,  1805,  655}, /* Subject to change at TELENET's whim */
  109.    { "NonPeak", WEEKEND,     0, 2400},
  110.    { "ROA",     WEEKDAY,  2205,  755}, /* Reach Out America (sm) (AT&T)       */
  111.    { "ROA",     SAT,         0, 2400}, /* Reach Out America (sm) (AT&T)       */
  112.    { "ROA",     SUN,      2205, 1655}, /* Reach Out America (sm) (AT&T)       */
  113.    { "Never",   NEVER,       0, 2400},
  114.    {  nil(char) }
  115. }; /* table */
  116.  
  117. /*--------------------------------------------------------------------*/
  118. /*    c h e c k t i m e                                               */
  119. /*                                                                    */
  120. /*    Validate a time of day field; returns lowest grade              */
  121. /*--------------------------------------------------------------------*/
  122.  
  123. char checktime(const char *xtime)
  124. {
  125.  
  126.    struct tm *tm_now;
  127.    time_t secs_now;
  128.    size_t hhmm;
  129.    char  buf[BUFSIZ];
  130.    char  *token;
  131.    char  *nexttoken;
  132.    char  bestgrade = '\0';    /* No grade found yet                  */
  133.    int   weekday;
  134.  
  135.    strcpy(buf,xtime);         /* Copy time to local buffer we can alter */
  136.    time(&secs_now);
  137.    tm_now = localtime(&secs_now);
  138.                                        /* Create structure with time    */
  139.    weekday = SUN >> tm_now->tm_wday;   /* Get day of week as single bit */
  140.    hhmm = tm_now->tm_hour*100 + tm_now->tm_min;
  141.    nexttoken = buf;           /* First pass, look at start of buffer    */
  142.  
  143.    while ((bestgrade < ALL_GRADES) &&
  144.           ((token = strtok(nexttoken,",")) != NULL))
  145.    {
  146.       char grade = checkone( token, hhmm, weekday);
  147.  
  148.       if ( bestgrade < grade )
  149.             bestgrade = grade;
  150.  
  151.       nexttoken = NULL;       /* Continue parsing same string           */
  152.  
  153.    } /* while (!(dial) && ((token = strtok(nexttoken,",")) != NULL) ) */
  154.  
  155. /*--------------------------------------------------------------------*/
  156. /*            Report our results and return to the caller             */
  157. /*--------------------------------------------------------------------*/
  158.  
  159.    return (bestgrade);
  160.  
  161. } /*checktime*/
  162.  
  163. /*--------------------------------------------------------------------*/
  164. /*    c h e c k o n e                                                 */
  165. /*                                                                    */
  166. /*    Process one time field for checktime                            */
  167. /*--------------------------------------------------------------------*/
  168.  
  169. static char checkone( char *input, size_t hhmm, int weekday )
  170. {
  171.    char  tdays[20];           /* String version of user tokens       */
  172.    char  tstart[20];
  173.    char  tend[20];
  174.    size_t istart;
  175.    size_t iend;
  176.    struct Table *tptr;
  177.    boolean dial = FALSE;      /* Assume we cannot dial               */
  178.    char  found = 0;           /* Did not yet find current keyword    */
  179.    char grade = ALL_GRADES;   /* Default grade if none specified     */
  180.  
  181.    char *slash = strchr( input, '/' );
  182.  
  183. /*--------------------------------------------------------------------*/
  184. /*     Parse a day/time combination from the L.SYS file         *     */
  185. /*--------------------------------------------------------------------*/
  186.  
  187.    strcpy(tstart,"0000");  /* Set default times to all day           */
  188.    strcpy(tend,"2400");
  189.  
  190. /*--------------------------------------------------------------------*/
  191. /*                      Determine the call grade                      */
  192. /*--------------------------------------------------------------------*/
  193.  
  194.    if ( slash != NULL )
  195.    {
  196.  
  197.       if (strlen( slash ) != 2)
  198.       {
  199.          printmsg(0,"Invalid call grade in field: %s", input );
  200.          panic();
  201.       }
  202.  
  203.       *slash++ = '\0';     /* Terminate original string              */
  204.       grade = *slash;      /* Save the grade the user wanted         */
  205.  
  206.    } /* if ( slash != NULL ) */
  207.  
  208. /*--------------------------------------------------------------------*/
  209. /*         Get the period and time limits the user specified          */
  210. /*--------------------------------------------------------------------*/
  211.  
  212.    sscanf(input,"%[A-Za-z]%[0-9]-%[0-9]", tdays, tstart, tend);
  213.  
  214. /*--------------------------------------------------------------------*/
  215. /*          Verify the lengths of the fields the user specified       */
  216. /*--------------------------------------------------------------------*/
  217.  
  218.    if (strlen(tstart) >= sizeof tstart)
  219.    {
  220.       printf( "%d character buffer overflow \"%s\"\n",
  221.                sizeof tstart , tstart );
  222.       panic();
  223.    }
  224.  
  225.    if (strlen(tend) >= sizeof tend)
  226.    {
  227.       printf( "%d character buffer overflow \"%s\"\n",
  228.                sizeof tend , tend );
  229.       panic();
  230.    }
  231.  
  232.    if (strlen(tdays) >= sizeof tdays)
  233.    {
  234.       printf( "%d character buffer overflow \"%s\"\n",
  235.                sizeof tdays, tdays );
  236.       panic();
  237.    }
  238.  
  239.    printmsg(8,"checkone: %s broken into \"%s\" from \"%s\" to \"%s\""
  240.               " with grade %c",
  241.             input,tdays,tstart,tend,grade );
  242.  
  243.    istart = atoi(tstart);  /* Convert start/end times to binary          */
  244.    iend  = atoi(tend);
  245.  
  246. /*--------------------------------------------------------------------*/
  247. /*    Handle case of midnight specified in such a way that the        */
  248. /*    time wraps through the daylight hours; we'll take the           */
  249. /*    conservative approach that the user really meant to start at    */
  250. /*    midnight.                                                       */
  251. /*--------------------------------------------------------------------*/
  252.  
  253.    if ((istart > iend) && (istart == 2400))
  254.       istart = 0000;
  255.  
  256. /*--------------------------------------------------------------------*/
  257. /*                  Search for the requested keyword                  */
  258. /*--------------------------------------------------------------------*/
  259.  
  260.    for (tptr = table, found = FALSE;
  261.          (tptr->keyword != nil(char)) && !dial; tptr++)
  262.    {
  263.  
  264. /*--------------------------------------------------------------------*/
  265. /*      We found the keyword, see if today qualifies for dialing      */
  266. /*--------------------------------------------------------------------*/
  267.  
  268.       if (equal(tptr->keyword,tdays))
  269.       {
  270.          found = TRUE;     /* Win or Lose, keyword is valid          */
  271.          if (weekday & tptr->wdays)    /* Can we dial out today?     */
  272.          {                             /* Yes --> Check the time     */
  273.  
  274. /*--------------------------------------------------------------------*/
  275. /*    This entry allows us to dial out today; now determine if the    */
  276. /*    time slot in the table allows dialing.                          */
  277. /*--------------------------------------------------------------------*/
  278.  
  279.             if (tptr->start > tptr->end)  /* span midnight?          */
  280.                dial = (tptr->start <= hhmm) || (tptr->end >= hhmm);
  281.             else
  282.                dial = (tptr->start <= hhmm) && (tptr->end >= hhmm);
  283.  
  284. /*--------------------------------------------------------------------*/
  285. /*    Now do a logical AND of that time with the time the user        */
  286. /*    specified in L.sys for this particular system.                  */
  287. /*--------------------------------------------------------------------*/
  288.  
  289.             if (istart > iend)            /* span midnight?          */
  290.                dial = ((istart <= hhmm) || (iend >= hhmm)) && dial;
  291.             else if (istart == iend)
  292.                dial = (istart == hhmm) && dial;
  293.             else
  294.                dial = (istart <= hhmm) && (iend >= hhmm) && dial;
  295.          } /* if */
  296.       } /* if */
  297.    } /* for */
  298.  
  299.    if (!found)
  300.       printmsg(0,"checkone: keyword \"%s\" not found",input);
  301.  
  302.    printmsg(3,"checkone: call window \"%s\" %s",
  303.          input,
  304.          dial ? "open" :"closed");
  305.  
  306. /*--------------------------------------------------------------------*/
  307. /*                Return success or failure to caller                 */
  308. /*--------------------------------------------------------------------*/
  309.  
  310.    if ( dial )
  311.       return grade;
  312.    else
  313.       return '\0';
  314.  
  315. } /* checkone */
  316.